﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices.AccountManagement;
using System.Web.Security;
using Microsoft.SharePoint;

namespace ContosoProviders
{
    public class LDAPRole : RoleProvider
    {

        private string _applicationName = string.Empty;
        public override string ApplicationName
        {
            get
            {
                if (_applicationName == string.Empty)
                {
                    _applicationName = SPContext.Current.Site.ID.ToString();
                }
                return _applicationName;
            }
            set
            {
                this._applicationName = SPContext.Current.Site.ID.ToString();
            }
        }

        public override string[] GetRolesForUser(string username)
        {
            try
            {
                List<string> userGroups = new List<string>();
                SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(delegate()
                {
                    using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
                    {
                        using (UserPrincipal user = UserPrincipal.FindByIdentity(context, username))
                        {
                            if (!(user == null))
                            {
                                PrincipalSearchResult<Principal> results = user.GetAuthorizationGroups();
                                foreach (GroupPrincipal group in results)
                                {
                                    userGroups.Add(group.SamAccountName);
                                }
                            }
                        }
                    }
                }));
                return userGroups.ToArray();
            }
            catch (Exception ex)
            {
                //Log Something
                return null;
            }
        }

        public override string[] GetUsersInRole(string roleName)
        {
            try
            {
                List<string> groupMembers = new List<string>();
                SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(delegate()
                {
                    using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
                    {
                        using (GroupPrincipal groupFilter = new GroupPrincipal(context))
                        {
                            groupFilter.SamAccountName = roleName;
                            foreach (GroupPrincipal group in groupFilter.GetMembers(true))
                            {
                                groupMembers.Add(group.SamAccountName);
                            }
                        }
                    }
                }));
                return groupMembers.ToArray();
            }
            catch (Exception ex)
            {
                //Log something.
                return null;
            }
        }

        public override bool RoleExists(string roleName)
        {
            try
            {
                bool result = false;
                SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(delegate()
                {
                    using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
                    {
                        using (GroupPrincipal groupFilter = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, roleName))
                        {
                            if (groupFilter != null)
                            {
                                result = groupFilter.IsSecurityGroup.Value;
                            }
                        }
                    }
                }));
                return result;
            }
            catch (Exception ex)
            {
                //Log something.
                return false;
            }
        }

        #region Not Implemented Methods
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }

        public override string[] GetAllRoles()
        {
            throw new NotImplementedException();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            throw new NotImplementedException();
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}